#pragma once

#include <stdio.h>
#include <GL/glut.h>
#include "vector3D.h"
#include <iostream>
#include "Camera.h"
#include "Projectile.h"
#include <irrKlang.h>

using namespace std;
using namespace irrklang;

// Scene Graph
#include "SceneGraph/Group.h"
#include "SceneGraph/Frustum.h"

typedef struct												// Create A Structure
{
	GLubyte	*imageData;										// Image Data (Up To 32 Bits)
	GLuint	bpp;											// Image Color Depth In Bits Per Pixel.
	GLuint	width;											// Image Width
	GLuint	height;											// Image Height
	GLuint	texID;											// Texture ID Used To Select A Texture
} TextureImage;												// Structure Name

//Mouse Info
typedef struct {
	bool mLButtonUp;
	bool mRButtonUp;
	bool middleButtonUp;
	int  lastX, lastY;
} theMouseInfo;

class myApplication 
{
public:
	// this is a constructor, it is implemented in myapplication.cpp
	myApplication();
	// this is a destructor, it is implemented in myapplication.cpp
	~myApplication();

//	bool Start( int argc, char **argv );

	bool Init();

	void renderScene(void);

	void changeSize(int w, int h);

	void inputKey(int key, int x, int y);
	void KeyboardDown(unsigned char key, int x, int y);
	void KeyboardUp(unsigned char key, int x, int y);
	void MouseMove (int x, int y);
	void MouseClick(int button, int state, int x, int y);

	static myApplication* getInstance();
	void drop();

private:
	
	static myApplication *s_pInstance;
	// Texture mapping
//	GLuint	texture[16];			// Storage For Grass Texture
	TextureImage grassTexture[5];
	TextureImage skyTexture[6];

	// Camera
	Vector3D theCameraPosition;
	Vector3D theCameraDirection;
	float angle;

	void Draw3DEnvironment();
	void Update(void);
	bool LoadTGA(TextureImage *texture, char *filename);			// Loads A TGA File Into Memory

	void moveMeForward(bool mode, float timeDiff);
	void moveMeSideway(bool mode, float timeDiff);

	void orientMe(float ang); 

	void renderGround(void);
	void renderSky(void);

	//  The number of frames
	int frameCount;
	//  Number of frames per second
	float fps;
	//  currentTime - previousTime is the time elapsed
	//  between every call of the Idle function
	int currentTime, previousTime;
	//  Pointer to a font style..
	//  Fonts supported by GLUT are: GLUT_BITMAP_8_BY_13, 
	//  GLUT_BITMAP_9_BY_15, GLUT_BITMAP_TIMES_ROMAN_10, 
	//  GLUT_BITMAP_TIMES_ROMAN_24, GLUT_BITMAP_HELVETICA_10,
	//  GLUT_BITMAP_HELVETICA_12, and GLUT_BITMAP_HELVETICA_18.
	//GLvoid *font_style;
	void *font_style;
	// Calculate the FPS
	void calculateFPS();
	// Display FPS
	void drawFPS();
	//  Draws a string at the specified coordinates.
	void printw (float x, float y, float z, char* format, ...);

	// realtime loop control
	long timelastcall;
	// realtime loop control - frequency
	float frequency;

	bool myKeys[255];
	theMouseInfo mouseInfo;

	// The camera
	Camera* theCamera;

	// The projectiles
	CProjectile* theProjectiles;
	const static int MAXPROJECTILES = 100;
	int m_iProjectileIndex;

	// The sound engine
	ISoundEngine* theSoundEngine;
	ISound* Sound_Footstep;

	float calculateDistanceMoved( float acceleration, float maxVelocity, float timeDiff );
	float previousVelocity;

	// Draw the healthbar in the OpenGL window
	int m_iHeightOfBar;
	int m_iWidthOfBar;
	void DrawHealthBar(const int m_iHealth, const int m_iMaxHealth);

	// The scene graph
	CGroup* theRoot;

	//The Frustum
	CFrustum* theFrustum;
};